home *** CD-ROM | disk | FTP | other *** search
/ T&A 2 the Maxx 3 / T and A 2 The Maxx Number 3.iso / viewers / unixview / xgiftar.z / xgiftar / sunraster.c < prev    next >
C/C++ Source or Header  |  1991-05-20  |  7KB  |  331 lines

  1. /* sunraster.c:
  2.  *
  3.  * sun rasterfile image type
  4.  *
  5.  * jim frost 09.27.89
  6.  *
  7.  * Copyright 1989, 1991 Jim Frost.
  8.  * See included file "copyright.h" for complete copyright information.
  9.  */
  10.  
  11. #include "copyright.h"
  12. #include "image.h"
  13. #include "sunraster.h"
  14.  
  15. /* SUPPRESS 558 */
  16. /* SUPPRESS 560 */
  17.  
  18. static void babble(name, header)
  19.      char           *name;
  20.      struct rheader *header;
  21. {
  22.   printf("%s is a", name);
  23.   switch (memToVal(header->type, 4)) {
  24.   case ROLD:
  25.     printf("n old-style");
  26.     break;
  27.   case RSTANDARD:
  28.     printf(" standard");
  29.     break;
  30.   case RRLENCODED:
  31.     printf(" run-length encoded");
  32.     break;
  33.   case RRGB:
  34.     printf(" RGB"); /* RGB format instead of BGR */
  35.     break;
  36.   case RTIFF:
  37.     printf(" TIFF");
  38.     break;
  39.   case RIFF:
  40.     printf(" RIFF");
  41.     break;
  42.   default:
  43.     printf(" unknown-type");
  44.   }
  45.   printf(" %dx%d", memToVal(header->width, 4), memToVal(header->height, 4));
  46.  
  47.   switch (memToVal(header->depth, 4)) {
  48.   case 1:
  49.     printf(" monochrome");
  50.     break;
  51.   case 8:
  52.     printf(" 8 plane %s",
  53.        memToVal(header->maplen, 4) > 0 ? "color" : "greyscale");
  54.     break;
  55.   case 24:
  56.     printf(" 24 plane color");
  57.     break;
  58.  
  59.   case 32:
  60.     /* isn't it nice how the sunraster.h file doesn't bother to mention that
  61.      * 32-bit depths are allowed?
  62.      */
  63.     printf(" 32 plane color");
  64.     break;
  65.   }
  66.   printf(" Sun rasterfile\n");
  67. }
  68.  
  69. int sunRasterIdent(fullname, name)
  70.      char *fullname, *name;
  71. { ZFILE          *zf;
  72.   struct rheader  header;
  73.   int             r;
  74.  
  75.   if (! (zf= zopen(fullname))) {
  76.     perror("sunRasterIdent");
  77.     return(0);
  78.   }
  79.   switch (zread(zf, (byte *)&header, sizeof(struct rheader))) {
  80.   case -1:
  81.     perror("sunRasterIdent");
  82.     r= 0;
  83.     break;
  84.  
  85.   case sizeof(struct rheader):
  86.     if (memToVal(header.magic, 4) != RMAGICNUMBER) {
  87.       r= 0;
  88.       break;
  89.     }
  90.     babble(name, &header);
  91.     r= 1;
  92.     break;
  93.  
  94.   default:
  95.     r= 0;
  96.     break;
  97.   }
  98.   zclose(zf);
  99.   return(r);
  100. }
  101.  
  102. /* read either rl-encoded or normal image data
  103.  */
  104.  
  105. static void sunread(zf, buf, len, enc)
  106.      ZFILE        *zf;
  107.      byte         *buf;
  108.      unsigned int  len;
  109.      unsigned int  enc;  /* true if encoded file */
  110. { static byte repchar, remaining= 0;
  111.  
  112.   /* rl-encoded read
  113.    */
  114.  
  115.   if (enc) {
  116.     while (len--)
  117.       if (remaining) {
  118.     remaining--;
  119.     *(buf++)= repchar;
  120.       }
  121.       else {
  122.     if (zread(zf, &repchar, 1) != 1) {
  123.       printf("sunRasterLoad: Bad read on image data\n");
  124.       exit(1);
  125.     }
  126.     if (repchar == RESC) {
  127.       if (zread(zf, &remaining, 1) != 1) {
  128.         printf("sunRasterLoad: Bad read on image data\n");
  129.         exit(1);
  130.       }
  131.       if (remaining == 0)
  132.         *(buf++)= RESC;
  133.       else {
  134.         if (zread(zf, &repchar, 1) != 1) {
  135.           printf("sunRasterLoad: Bad read on image data\n");
  136.           exit(1);
  137.         }
  138.         *(buf++)= repchar;
  139.       }
  140.     }
  141.     else
  142.       *(buf++)= repchar;
  143.       }
  144.   }
  145.  
  146.   /* normal read
  147.    */
  148.  
  149.   else {
  150.     if (zread(zf, buf, len) < len) {
  151.       printf("sunRasterLoad: Bad read on image data\n");
  152.       exit(1);
  153.     }
  154.   }
  155. }
  156.  
  157. Image *sunRasterLoad(fullname, name, verbose)
  158.      char         *fullname, *name;
  159.      unsigned int  verbose;
  160. { ZFILE          *zf;
  161.   struct rheader  header;
  162.   unsigned int    mapsize;
  163.   byte           *map;
  164.   byte           *mapred, *mapgreen, *mapblue;
  165.   unsigned int    depth;
  166.   unsigned int    linelen;   /* length of raster line in bytes */
  167.   unsigned int    fill;      /* # of fill bytes per raster line */
  168.   unsigned int    enc;
  169.   byte            fillchar;
  170.   Image          *image;
  171.   byte           *lineptr;
  172.   unsigned int    x, y;
  173.  
  174.   if (! (zf= zopen(fullname))) {
  175.     perror("sunRasterLoad");
  176.     return(NULL);
  177.   }
  178.   switch (zread(zf, (byte *)&header, sizeof(struct rheader))) {
  179.   case -1:
  180.     perror("sunRasterLoad");
  181.     zclose(zf);
  182.     exit(1);
  183.  
  184.   case sizeof(struct rheader):
  185.     if (memToVal(header.magic, 4) != RMAGICNUMBER) {
  186.       zclose(zf);
  187.       return(NULL);
  188.     }
  189.     if (verbose)
  190.       babble(name, &header);
  191.     break;
  192.  
  193.   default:
  194.     zclose(zf);
  195.     return(NULL);
  196.   }
  197.  
  198.   znocache(zf); /* turn off caching; we don't need it anymore */
  199.  
  200.   /* get an image to put the data in
  201.    */
  202.  
  203.   depth= memToVal(header.depth, 4);
  204.   switch(depth) {
  205.   case 1:
  206.     image= newBitImage(memToVal(header.width, 4),
  207.                memToVal(header.height, 4));
  208.     break;
  209.   case 8:
  210.     image= newRGBImage(memToVal(header.width, 4),
  211.                memToVal(header.height, 4),
  212.                memToVal(header.depth, 4));
  213.     break;
  214.   case 24:
  215.   case 32:
  216.     image= newTrueImage(memToVal(header.width, 4),
  217.                memToVal(header.height, 4),
  218.                memToVal(header.depth, 4));
  219.     break;
  220.   default:
  221.     printf("sunRasterLoad: Bad depth %d (only 1, 8, 24 are valid)\n", depth);
  222.     exit(1);
  223.   }
  224.  
  225.   /* set up the colormap
  226.    */
  227.  
  228.   if (depth == 1)
  229.     linelen= (image->width / 8) + (image->width % 8 ? 1 : 0);
  230.   else
  231.     linelen= image->width * image->pixlen;
  232.   fill= (linelen % 2 ? 1 : 0);
  233.   /*
  234.    *  Handle color...
  235.    */
  236.   if (mapsize= memToVal(header.maplen, 4)) {
  237.     map= lmalloc(mapsize);
  238.     if (zread(zf, map, mapsize) < mapsize) {
  239.       printf("sunRasterLoad: Bad read on colormap\n");
  240.       exit(1);
  241.     }
  242.     mapsize /= 3;
  243.     mapred= map;
  244.     mapgreen= mapred + mapsize;
  245.     mapblue= mapgreen + mapsize;
  246.     if (image->rgb.size == 0)
  247.     newRGBMapData(&image->rgb, mapsize);
  248.     for (y= 0; y < mapsize; y++) {
  249.       *(image->rgb.red + y)= (*(mapred++) << 8);
  250.       *(image->rgb.green + y)= (*(mapgreen++) << 8);
  251.       *(image->rgb.blue + y)= (*(mapblue++) << 8);
  252.     }
  253.     lfree(map);
  254.     image->rgb.used= mapsize;
  255.   }
  256.  
  257.   /*
  258.    *  Handle 8-bit greyscale via a simple ramp function...
  259.    */
  260.   else if (depth == 8) {
  261.     mapsize = 256*3;
  262.     map= lmalloc(mapsize);
  263.     for (y = 0; y < 256; y += 1) {
  264.       map[y] = map[256+y] = map[2*256+y] = y;
  265.     }
  266.     mapsize /= 3;
  267.     mapred= map;
  268.     mapgreen= mapred + mapsize;
  269.     mapblue= mapgreen + mapsize;
  270.     if (image->rgb.size == 0)
  271.     newRGBMapData(&image->rgb, mapsize);
  272.     for (y= 0; y < mapsize; y++) {
  273.       *(image->rgb.red + y)= (*(mapred++) << 8);
  274.       *(image->rgb.green + y)= (*(mapgreen++) << 8);
  275.       *(image->rgb.blue + y)= (*(mapblue++) << 8);
  276.     }
  277.     lfree(map);
  278.     image->rgb.used= mapsize;
  279.   }
  280.   /* 24-bit and 32-bit handle themselves.  currently we don't support
  281.    * a colormap for them.
  282.    */
  283.  
  284.   enc= (memToVal(header.type, 4) == RRLENCODED);
  285.   lineptr= image->data;
  286.  
  287.   /* if it's a 32-bit image, we read the line and then strip off the
  288.    * top byte of each pixel to get truecolor format
  289.    */
  290.  
  291.   if (depth >= 24) {
  292.     byte *buf, *bp;
  293.  
  294.     buf= lmalloc(image->width * (depth == 24 ? 3 : 4));
  295.     for (y= 0; y < image->height; y++) {
  296.       sunread(zf, buf, image->width * (depth == 24 ? 3 : 4), enc);
  297.       bp= buf;
  298.       if (depth == 24) {
  299.        for (x= 0; x < image->width; x++) {
  300.         *(lineptr++)= *(bp + 2); /* red */
  301.         *(lineptr++)= *(bp + 1); /* green */
  302.         *(lineptr++)= *bp;       /* blue */
  303.         bp += 3;
  304.        }
  305.       }
  306.       else {
  307.        for (x= 0; x < image->width; x++) {
  308.         *(lineptr++)= *(bp + 3); /* red */
  309.         *(lineptr++)= *(bp + 2); /* green */
  310.         *(lineptr++)= *(bp + 1); /* blue */
  311.         bp += 4;
  312.        }
  313.       }
  314.       if (fill)
  315.     sunread(zf, &fillchar, fill, enc);
  316.     }
  317.     lfree(buf);
  318.   }
  319.   else {
  320.     for (y= 0; y < image->height; y++) {
  321.       sunread(zf, lineptr, linelen, enc);
  322.       lineptr += linelen;
  323.       if (fill)
  324.     sunread(zf, &fillchar, fill, enc);
  325.     }
  326.   }
  327.   zclose(zf);
  328.   image->title= dupString(name);
  329.   return(image);
  330. }
  331.